#include "sigmafns.h"
#include "sigmalib.h"

/* EVENT FUNCTIONS USED IN THE SIMULATION MODEL */
void P1_START(void);
void P1_START(void);
void P2_START(void);
void P2_START(void);
void P3_START(void);
void P3_START(void);
void P4_START(void);
void P4_START(void);
void P5_START(void);
void P5_START(void);
void SORT(void);
void RUN(void);
void ARRIVE(void);
void INIT(void);
void RUN(void);

/*   STATE VARIABLE DELARATIONS   */
long PMAX;
long PRDMAX;
long PDATA;
long PRDDATA;
long NEXTPRD;
long QT;
long PTYPE;
long ITER;
long PID;
long QPRD[100];
long STAFF;
long PRIORITY;
long QLEAVE;

/*   EVENT FUNCTIONS   */
enum {
run_end_event,
P1_START_event,
P1_START_event,
P2_START_event,
P2_START_event,
P3_START_event,
P3_START_event,
P4_START_event,
P4_START_event,
P5_START_event,
P5_START_event,
SORT_event,
RUN_event,
ARRIVE_event,
INIT_event,
RUN_event,
};

/*    MAIN PROGRAM     */
int main(int argc, char** argv) {
int  next_event;
char keytoclose = 'p';

if(!startup_check(0))
return -1;

/* Initialize csiglib and simulation */
while (initialize(argc, (const char * *)argv)) {;

/* Schedule beginning of simulation */
event_time = current_time;
event_type = RUN_event;
schedule_event();

/* Schedule end of simulation */
event_time = stop_time;
event_type = run_end_event;
event_priority = 9999;
schedule_event();

/* EVENT EXECUTION CONTROL LOOP */
while (!run_error && !done) {
/* Pull next event from event list */
next_event = c_timing();

/* increment the event count for this event */
event_count[next_event]++;

/* Call appropriate event routine */
switch ( next_event ) {
case run_end_event:  run_end();
break;

case P1_START_event: P1_START();
event_trace("P1_START",event_count[next_event]);
break;

case P1_START_event: P1_START();
event_trace("P1_START",event_count[next_event]);
break;

case P2_START_event: P2_START();
event_trace("P2_START",event_count[next_event]);
break;

case P2_START_event: P2_START();
event_trace("P2_START",event_count[next_event]);
break;

case P3_START_event: P3_START();
event_trace("P3_START",event_count[next_event]);
break;

case P3_START_event: P3_START();
event_trace("P3_START",event_count[next_event]);
break;

case P4_START_event: P4_START();
event_trace("P4_START",event_count[next_event]);
break;

case P4_START_event: P4_START();
event_trace("P4_START",event_count[next_event]);
break;

case P5_START_event: P5_START();
event_trace("P5_START",event_count[next_event]);
break;

case P5_START_event: P5_START();
event_trace("P5_START",event_count[next_event]);
break;

case SORT_event: SORT();
event_trace("SORT",event_count[next_event]);
break;

case RUN_event: RUN();
event_trace("RUN",event_count[next_event]);
break;

case ARRIVE_event: ARRIVE();
event_trace("ARRIVE",event_count[next_event]);
break;

case INIT_event: INIT();
event_trace("INIT",event_count[next_event]);
break;

case RUN_event: RUN();
event_trace("RUN",event_count[next_event]);
break;

}
}
}
// experiments terminated
return 0;
}

void event_trace(const char * name_of_event,const long count) {
c_timest(QT, 1, 0);
c_sampst(QT, 1, 0);
if(trace_flag) fprintf(output_fp, "%9.3f	 %6s	%6d ",current_time,name_of_event,count);
if(trace_flag) fprintf(output_fp, "	%7.3g 
"
,(double)QT);
}

int initialize (int argc, const char** argv) {
static int first_time = 1;
static FILE *input_fp; 
char *exp_file_name;
char y_n = 'p';

char dir[256];
char fname[256];
char ext[256];
char simulation[1024];
char experient_name[1024];
_splitpath( argv[0], NULL, dir, fname, ext );
strcpy(simulation, fname);
strcat(simulation, ext);
strcpy(experient_name, fname);
strcat(experient_name, ".exp");
printf("Running the simulation: %s
", simulation);
if(strlen(dir) !=0)
printf("In Path: %s
",dir);
if (first_time) {
exp_file_name = _strdup(argv[0]);
exp_file_name[strlen(exp_file_name)-1] = 'p';
printf("
Looking for experiment file: %s
",experient_name);
}

if ((first_time && (input_fp=fopen(exp_file_name,"r"))!=NULL) || input_fp!=NULL) {
if (first_time) {
first_time = 0; /* Reset for next time into initialize */
printf("Found. Use [Control]-C to abort replications.
");
}

/* We have run control file of type *.exp */
/* Read next set of data from run control file. */
if (fscanf(input_fp,"%s %1s %ld %lf %d", output_file_name, &y_n, &rndsd, &stop_time, &trace_flag)<4) {
/* End of run control file */
fclose(input_fp);
return 0;
}

done = 0;
}
}

void run_end() {
printf("
Normal completion after %f time units
",current_time);
printf("The Next Seed In the Random Input Stream is %ld
",rndsd);

///  Summary statistics ///
fprintf(output_fp,"SUMMARY STATISTICS
");
printf("SUMMARY STATISTICS
");
c_timest(QT, 1, 1);
fprintf(output_fp, "QT:
 Time Ave. = 	%7.4g Time Sample Var. =	%7.4g
", transfer[4], transfer[7]);
c_sampst(QT, 1, 1);
fprintf(output_fp, " Event Ave. =	%7.4g Event Sample Var. =	%7.4g
", transfer[4], transfer[8]);
fprintf(output_fp, " Minimum =	%7.4g
", transfer[7]);
fprintf(output_fp, " Maximum =	%7.4g
", transfer[6]);
printf(" Event Ave.  = 	%7.4g Event Sample Var.= 	%7.4g
", transfer[4], transfer[8]);
printf(" Minimum  = 	%7.4g
", transfer[7]);
printf(" Maximum  = 	%7.4g
", transfer[6]);
printf("Output written to, %s
",output_file_name);
fclose(output_fp);
c_closedisk();
done = 1;
}





/****************************/
/*     EVENT FUNCTIONS      */
/****************************/
















